﻿/*code is far away from bug with the animal protecting
*  ┏┓　　　┏┓
*┏┛┻━━━┛┻┓
*┃　　　　　　　┃ 　
*┃　　　━　　　┃
*┃　┳┛　┗┳　┃
*┃　　　　　　　┃
*┃　　　┻　　　┃
*┃　　　　　　　┃
*┗━┓　　　┏━┛
*　　┃　　　┃
*　　┃　　　┃
*　　┃　　　┗━━━┓
*　　┃　神兽保佑　　┣┓
*　　┃　代码无BUG！ ┏┛
*　　┗┓┓┏━┳┓┏┛
*　　　┃┫┫　┃┫┫
*　　　┗┻┛　┗┻┛ 
*　　　
*/

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Middleware.Extenssion
{
    public class AccessSessionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly AuthOptions _options;
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="next"></param>
        /// <param name="options"></param>
        public AccessSessionMiddleware(RequestDelegate next, IOptions<AuthOptions> options)
        {
            _next = next;
            _options = options.Value;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            if (context.User.Identity.IsAuthenticated)
            {
            
                await GetSession(context);
               
            }
            await _next(context);
        }
        /// <summary>
        /// 返回信息
        /// </summary>
        /// <param name="context"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task ResponseUnauthorized(HttpContext context, int code)
        {
            context.Response.StatusCode = code;
            if (code == 401)
            {
                var res = "登陆过期。";

                await context.Response.WriteAsync(res);
                return;
            }
            if (code == 403)
            {
                var res = "无权限。";

                await context.Response.WriteAsync(res);
                return;
            }
            if (code == 500)
            {
                var res = "服务器维护中。";

                await context.Response.WriteAsync(res);
                return;
            }
        }
        /// <summary>
        /// 登陆者信息提取
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task GetSession(HttpContext context)
        {
            var session = context.Items.GetUser();
            var jtiClaim = context.User.Claims.FirstOrDefault(m => m.Type == "jti");
            //ar jti = string.Empty;
            if (jtiClaim == null || string.IsNullOrWhiteSpace(jtiClaim.Value))
            {
                await ResponseUnauthorized(context, 401);
            }

            var userClaim = context.User.Claims.FirstOrDefault(m => m.Type == nameof(UserSessionDto.UserId));
            var userId = 0;
            if (userClaim == null || !int.TryParse(userClaim.Value, out userId))
            {
                await ResponseUnauthorized(context, 401);
            }
       
            if (session == null)
                session = new UserSessionDto();
            session.UserId = userId;
            session.RealName = context.User.Claims.FirstOrDefault(m => m.Type == nameof(UserSessionDto.RealName)).Value;
            session.UserName = context.User.Claims.FirstOrDefault(m => m.Type == nameof(UserSessionDto.UserName)).Value;
            int.TryParse(context.User.Claims.FirstOrDefault(m => m.Type == nameof(UserSessionDto.RoleId)).Value, out int roleid);
            session.RoleId = roleid;
          
            context.Items.SetUser(session);
        }
    }
}
